home *** CD-ROM | disk | FTP | other *** search
- /*
- * install2.c
- *
- * This is the second half of the install. It is exec'd from the first half
- * once the secondary media has been mounted. It does a bunch of argv
- * processing to figure out what the first half did. It's a bit of a hack, but
- * it gives us a nice install as far as the user can see.
- *
- * Erik Troan (ewt@redhat.com)
- *
- * Copyright 1997 Red Hat Software
- *
- * This software may be freely redistributed under the terms of the GNU
- * public license.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- /*
- * We assume the following:
- *
- * /usr/bin -> any binaries we might need
- *
- * it's up to the first stage installer to make sure this happens.
- *
- */
-
- #include <dirent.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <newt.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/sysmacros.h>
- #include <sys/time.h>
- #include <sys/wait.h>
- #include <termios.h>
- #include <unistd.h>
-
- #include "commands.h"
- #include "config.h"
- #include "devices.h"
- #include "doit.h"
- #include "fs.h"
- #include "hd.h"
- #include "install.h"
- #include "kbd.h"
- #include "kernel.h"
- #include "lilo.h"
- #include "log.h"
- #include "methods.h"
- #include "mkswap.h"
- #include "net.h"
- #include "perror.h"
- #include "pkgs.h"
- #include "printercfg.h"
- #include "run.h"
- #include "scsi.h"
- #include "upgrade.h"
- #include "windows.h"
-
- int testing = 0;
-
- #define STEP_FIRST 0
-
- #define STEP_PATH 0
- #define STEP_SCSI 1
- #define STEP_FDISK 2
- #define STEP_SWAP 3
- #define STEP_FINDPKGS 4
- #define STEP_MTAB 5
- #define STEP_FORMAT 6
- #define STEP_PICKPKGS 7
- #define STEP_DOIT 8
- #define STEP_FINISHNET 9
- #define STEP_TIMECONFIG 10
- #define STEP_PRINTER 11
- #define STEP_ROOTPW 12
- #define STEP_LILO 13
-
- #define STEP_UPG_SCSI 1
- #define STEP_UPG_PKGS 2
- #define STEP_UPG_MTAB 3
- #define STEP_UPG_FFILES 4
- #define STEP_UPG_DOIT 5
- #define STEP_UPG_FINISHNET 6
- #define STEP_UPG_LILO 7
-
- #define STEP_DONE 1000
-
- struct installState {
- int isUpgrade, lastChoice;
- char * pcmcia, * kernel, * keyboard;
- struct partitionTable table;
- struct fstab fstab;
- struct pkgSet ps;
- struct componentSet cs;
- struct installMethod * method;
- struct netInterface intf;
- struct netConfig netc;
- struct driversLoaded * dl;
- struct installStep * steps;
- } ;
-
- typedef int (*installStepFn)(struct installState * state);
-
- static int setupSCSI(struct installState * state);
- static int partitionDisks(struct installState * state);
- static int setupSwap(struct installState * state);
- static int findInstallFiles(struct installState * state);
- static int setupFilesystem(struct installState * state);
- static int formatPartitions(struct installState * state);
- static int choosePackages(struct installState * state);
- static int doInstallStep(struct installState * state);
- static int setRootPassword(struct installState * state);
- static int configureTimezone(struct installState * state);
- static int configurePrinter(struct installState * state);
- static int setupBootloader(struct installState * state);
- static int finishNetworking(struct installState * state);
- static int selectPath(struct installState * state);
- static int upgrChoosePackages(struct installState * state);
- static int upgrFindInstall(struct installState * state);
- static void setupSerialConsole(void);
-
- struct installStep {
- char * name;
- int prev, next;
- installStepFn fn;
- int skipOnCancel;
- int completed;
- };
-
- struct installStep installSteps[] = {
- { "Select installation path", -1, STEP_SCSI,
- selectPath, 0, 0 },
- { "Setup SCSI", STEP_PATH, STEP_FDISK,
- setupSCSI, 0, 0 },
- { "Partition disks", STEP_PATH, STEP_SWAP,
- partitionDisks, 0, 0 },
- { "Setup swap space", STEP_FDISK, STEP_FINDPKGS,
- setupSwap, 0, 0 },
- { "Find installation files", STEP_SWAP, STEP_MTAB,
- findInstallFiles, 1, 0 },
- { "Setup filesystems", STEP_SWAP, STEP_FORMAT,
- setupFilesystem, 0, 0 },
- { "Choose partitions to format", STEP_MTAB, STEP_PICKPKGS,
- formatPartitions, 0, 0 },
- { "Choose packages to install", STEP_FORMAT, STEP_DOIT,
- choosePackages, 0, 0 },
- { "Install system", -1, STEP_FINISHNET,
- doInstallStep, 0, 0 },
- { "Configure networking", -1, STEP_TIMECONFIG,
- finishNetworking, 0, 0 },
- { "Configure timezone", STEP_FINISHNET, STEP_PRINTER,
- configureTimezone, 0, 0 },
- { "Configure printer", STEP_TIMECONFIG, STEP_ROOTPW,
- configurePrinter, 0, 0 },
- { "Set root password", STEP_PRINTER, STEP_LILO,
- setRootPassword, 0, 0 },
- { "Install bootloader", STEP_ROOTPW, STEP_DONE,
- setupBootloader, 0, 0 },
- };
-
- struct installStep upgradeSteps[] = {
- { "Select installation path", -1, STEP_UPG_SCSI,
- selectPath, 0, 0 },
- { "Setup SCSI", STEP_PATH, STEP_UPG_PKGS,
- setupSCSI, 0, 0 },
- { "Find installation files", STEP_PATH, STEP_UPG_MTAB,
- findInstallFiles, 1, 0 },
- { "Find current installation", STEP_UPG_PKGS, STEP_UPG_FFILES,
- upgrFindInstall, 0, 0 },
- { "Choose packages to upgrade", STEP_UPG_FFILES,STEP_UPG_DOIT,
- upgrChoosePackages, 0, 0 },
- { "Upgrade system", -1, STEP_UPG_FINISHNET,
- doInstallStep, 0, 0 },
- { "Install bootloader", STEP_UPG_FINISHNET, STEP_DONE,
- setupBootloader, 0, 0 },
- };
-
- void spawnShell(void) {
- pid_t pid;
- int fd;
-
- if (!testing) {
- fd = open("/dev/tty2", O_RDWR);
- if (fd < 0) {
- logMessage("cannot open /dev/tty2 -- no shell will be provided");
- return;
- } else if (access("/usr/bin/sh", X_OK)) {
- logMessage("cannot open shell - /usr/bin/sh doesn't exist");
- return;
- }
-
- if (!(pid = fork())) {
- dup2(fd, 0);
- dup2(fd, 1);
- dup2(fd, 2);
-
- close(fd);
- setsid();
-
- execl("/bin/sh", "-/bin/sh", NULL);
- logMessage(perrorstr("exec of /bin/sh failed"));
- }
-
- close(fd);
- }
- }
-
- static int setupSCSI(struct installState * state) {
- return setupSCSIInterfaces(0, &state->dl);
- }
-
- static int partitionDisks(struct installState * state) {
- int rc;
-
- if (!state->isUpgrade) {
- rc = partitionDrives();
- if (rc) return rc;
- }
-
- return findAllPartitions(&state->table);
- }
-
- static int findInstallFiles(struct installState * state) {
- int rc;
-
- if (!state->table.parts) {
- rc = findAllPartitions(&state->table);
- if (rc) return rc;
- }
-
- if (state->method->prepareRoot) {
- rc = state->method->prepareRoot(state->method, state->table,
- &state->netc, &state->intf,
- &state->dl);
- if (rc) return rc;
- }
-
- if ((rc = state->method->getPackageSet(state->method, &state->ps)))
- return rc;
- if ((state->method->getComponentSet(state->method, &state->ps,
- &state->cs)) )
- return rc;
-
- return 0;
- }
-
- static int setupFilesystem(struct installState * state) {
- return setupMountTable(state->table, &state->fstab, &state->intf,
- &state->netc, &state->dl);
- }
-
- static int formatPartitions(struct installState * state) {
- return queryFormatFilesystems(&state->fstab);
- }
-
- static int setupSwap(struct installState * state) {
- return activeSwapSpace(&state->table, &state->fstab);
- }
-
- static int choosePackages(struct installState * state) {
- return psSelectPackages(&state->ps, &state->cs, 0, 0);
- }
-
- static int doInstallStep(struct installState * state) {
- int rc;
- char * netSharedPath = NULL;
- FILE * f;
- int netSharedLength;
- int i;
-
- if (!state->isUpgrade) {
- winMessage(15, 7, 50, 10, "Install log", "A complete log "
- "of your installation will be in /tmp/install.log "
- "after rebooting your system. You may want to keep "
- "this file for later reference.");
-
- rc = formatFilesystems(&state->fstab);
- if (rc) return rc;
-
- rc = mountFilesystems(&state->fstab);
- if (rc) return rc;
-
- if (state->method->prepareMedia) {
- rc = state->method->prepareMedia(state->method, &state->fstab);
- if (rc) {
- umountFilesystems(&state->fstab);
- return rc;
- }
- }
- } else {
- winMessage(15, 7, 50, 10, "Upgrade log", "A complete log "
- "of your upgrade will be in /tmp/upgrade.log when "
- "the upgrade is finished. After rebooting, please "
- "read it to ensure configuration files are properly "
- "updated.");
- }
-
- /* FIXME: should this read the net shared path from /etc/rpmrc
- during upgrades??? Probably. */
- for (i = netSharedLength = 0; i < state->fstab.numEntries; i++)
- if (state->fstab.entries[i].type == PART_NFS)
- netSharedLength += 1 + strlen(state->fstab.entries[i].mntpoint);
-
- if (netSharedLength) {
- netSharedPath = alloca(netSharedLength);
- *netSharedPath = '\0';
- for (i = netSharedLength = 0; i < state->fstab.numEntries; i++) {
- if (state->fstab.entries[i].type == PART_NFS) {
- if (*netSharedPath) strcat(netSharedPath, ":");
- strcat(netSharedPath, state->fstab.entries[i].mntpoint);
- }
- }
-
- logMessage("netSharedPath is: %s\n", netSharedPath);
- }
-
- rc = doInstall(state->method, state->cs.preskel, &state->ps,
- netSharedPath, state->keyboard, state->isUpgrade);
-
- if (netSharedPath && access("/mnt/etc/rpmrc", X_OK)) {
- logMessage("creating /etc/rpmrc for netshared info (as none exists)");
- f = fopen("/mnt/etc/rpmrc", "w");
- if (!f) {
- errorWindow("error creating /mnt/etc/rpmrc: %s");
- } else {
- fprintf(f, "netsharedpath: %s\n", netSharedPath);
- fclose(f);
- }
- }
-
- sync();
- sync();
-
- if (!rc) psFreeComponentSet(&state->cs);
-
- configPCMCIA(state->pcmcia);
-
- return rc;
- }
-
-
- static char mksalt(int seed) {
- int num = seed % 64;
-
- if (num < 26)
- return 'a' + num;
- else if (num < 52)
- return 'A' + (num - 26);
- else if (num < 62)
- return '0' + (num - 52);
- else if (num == 63)
- return '.';
- else
- return '/';
- }
-
- static int setRootPassword(struct installState * state) {
- newtComponent form, text, pw1Entry, pw2Entry;
- char * pw1, * pw2;
- int done = 0;
- char salt[3];
- char cmd[200];
- struct timeval time1, time2;
- char * pw;
-
- gettimeofday(&time1, NULL);
-
- newtOpenWindow(15, 4, 50, 14, "Root Password");
-
- form = newtForm(NULL, NULL, 0);
-
- text = newtTextbox(1, 1, 47, 5, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text,
- "Pick a root password. You must type it twice to ensure you know "
- "what it is and didn't make a mistake in typing. Remember that the "
- "root password is a critical part of system security!");
-
- newtFormAddComponent(form, newtLabel(3, 7, "Password :"));
- newtFormAddComponent(form, newtLabel(3, 8, "Password (again):"));
-
- pw1Entry = newtEntry(21, 7, "", 24, &pw1, NEWT_ENTRY_HIDDEN);
- pw2Entry = newtEntry(21, 8, "", 24, &pw2, NEWT_ENTRY_HIDDEN);
-
- newtFormAddComponents(form, text, pw1Entry, pw2Entry, NULL);
-
- newtFormAddComponent(form, newtButton(20, 10, "Ok"));
-
- do {
- newtFormSetCurrent(form, pw1Entry);
- newtRunForm(form);
-
- if (testing) {
- done = 1;
- } else if (strcmp(pw1, pw2)) {
- winMessage(40, 11, 30, 9, "Password Mismatch",
- "The passwords you entered were different. Please "
- "try again.");
- newtEntrySet(pw1Entry, "", 0);
- newtEntrySet(pw2Entry, "", 0);
- } else if (strlen(pw1) < 6) {
- winMessage(40, 10, 30, 9, "Password Mismatch",
- "The root password must be at least 6 characters "
- "long.");
- newtEntrySet(pw1Entry, "", 0);
- newtEntrySet(pw2Entry, "", 0);
- } else
- done = 1;
- } while (!done);
-
- newtPopWindow();
-
- if (testing) return 0;
-
- gettimeofday(&time2, NULL);
-
- salt[0] = mksalt(time1.tv_usec);
- salt[1] = mksalt(time2.tv_usec);
- salt[2] = '\0';
-
- pw = crypt(pw1, salt);
-
- sprintf(cmd, "/mnt/bin/sed 's&root::&root:%s:&' < /mnt/etc/passwd > "
- "/mnt/etc/passwd.new", pw);
-
- newtFormDestroy(form);
-
- system(cmd);
- unlink("/mnt/etc/passwd");
- rename("/mnt/etc/passwd.new", "/mnt/etc/passwd");
-
- return 0;
- }
-
- static int configureTimezone(struct installState * state) {
- return timeConfig();
- }
-
- static int setupBootloader(struct installState * state) {
- static int first = 1;
- #ifdef __alpha
- int rc;
- #else
- int rc;
- int append = 0;
- char * version;
- int i;
- #endif
-
- if (!state->isUpgrade && first) {
- writeFstab(&state->fstab);
- setupSerialConsole();
- }
-
- #ifdef __alpha__
- if (first) {
- first = 0;
- rc = kernelCopy(state->kernel);
- if (rc) return rc;
- }
-
- return INST_NOP;
- #else
- first = 0;
-
- if (state->isUpgrade && !access("/mnt/etc/conf.modules", X_OK)) {
- rc = readModuleConfPersist("/mnt/etc", state->dl);
- if (rc) return rc;
- append = 1;
- }
-
- writeModuleConf("/mnt/etc", state->dl, 1);
-
- for (i = 0; i < state->ps.numPackages; i++) {
- if (!strncmp(state->ps.packages[i]->name, "kernel", 6)) break;
- }
-
- if (i == state->ps.numPackages) {
- errorWindow("I couldn't find a kernel!");
- return INST_ERROR;
- }
-
- headerGetEntry(state->ps.packages[i]->h, RPMTAG_VERSION, NULL,
- (void *) &version, NULL);
-
- logMessage("installed kernel version %s", version);
-
- /* installLilo installs silo on the SPARC */
- return installLilo("/mnt/etc", state->table, state->fstab, version);
- #endif
- }
-
- static int finishNetworking(struct installState * state) {
- int rc;
-
- rc = checkNetConfig(&state->intf, &state->netc, &state->dl);
- if (rc) return rc;
-
- writeNetConfig("/mnt/etc/sysconfig", &state->netc, &state->intf, 0);
- writeNetInterfaceConfig("/mnt/etc/sysconfig/network-scripts", &state->intf);
- writeResolvConf("/mnt/etc", &state->netc);
- writeHosts("/mnt/etc", &state->netc, &state->intf);
-
- return 0;
- }
-
- static int selectPath(struct installState * state) {
- newtComponent install, upgrade, text, f, answer;
-
- memset(state, 0, sizeof(state));
-
- newtOpenWindow(15, 6, 50, 10, "Installation Path");
-
- text = newtTextbox(1, 1, 47, 3, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text,
- "Would you like to install a new system or upgrade a system which "
- "already contains Red Hat 2.0 or later?");
-
- install = newtButton(10, 6, "Install");
- upgrade = newtButton(30, 6, "Upgrade");
-
- f = newtForm(NULL, NULL, 0);
- newtFormAddComponents(f, text, install, upgrade, NULL);
-
- answer = newtRunForm(f);
- if (answer == f)
- answer = newtFormGetCurrent(f);
-
- newtFormDestroy(f);
- newtPopWindow();
-
- if (answer == upgrade) {
- state->steps = upgradeSteps;
- state->isUpgrade = 1;
- } else
- state->steps = installSteps;
-
- return 0;
- }
-
- static int upgrFindInstall(struct installState * state) {
- int rc;
-
- /* this also turns on swap for us */
- rc = readMountTable(state->table, &state->fstab);
- if (rc) return rc;
-
- if (!testing) {
- mountFilesystems(&state->fstab);
-
- if (state->method->prepareMedia) {
- rc = state->method->prepareMedia(state->method, &state->fstab);
- if (rc) {
- umountFilesystems(&state->fstab);
- return rc;
- }
- }
- }
-
- return 0;
- }
-
- static int upgrChoosePackages(struct installState * state) {
- int firstTime = 1;
- char * upgradeList, * rpmconvertbin;
- int rc;
- char * path;
- char * argv[] = { NULL, NULL };
-
- if (testing)
- path = "/";
- else
- path = "/mnt";
-
- if (firstTime) {
- if (access("/mnt/var/lib/rpm/packages.rpm", R_OK)) {
- if (access("/mnt/var/lib/rpm/packages", R_OK)) {
- errorWindow("No RPM database exists!");
- return INST_ERROR;
- }
-
- if (state->method->getFile(state->method, "rpmconvert",
- &rpmconvertbin, 1)) {
- return INST_ERROR;
- }
-
- symlink("/mnt/var", "/var");
- winStatus(35, 3, "Upgrade", "Converting RPM database...");
- chmod(rpmconvertbin, 0755);
- argv[0] = rpmconvertbin;
- rc = runProgram(RUN_LOG, rpmconvertbin, argv);
- if (state->method->rmFiles)
- unlink(rpmconvertbin);
-
- newtPopWindow();
- if (rc) return INST_ERROR;
- }
-
- winStatus(35, 3, "Upgrade", "Finding packages to upgrade...");
- if (state->method->getFile(state->method, "uglist", &upgradeList, 1))
- return INST_ERROR;
- rc = ugFindUpgradePackages(&state->ps, path, upgradeList);
- if (state->method->rmFiles)
- unlink(upgradeList);
- newtPopWindow();
- if (rc) return rc;
- firstTime = 0;
- psVerifyDependencies(&state->ps, 1);
- }
-
- return psSelectPackages(&state->ps, &state->cs, 0, 1);
- }
-
- #define DO_RETRY 1
- #define DO_NEXT 2
- #define DO_PREV 3
- #define DO_MENU 4
-
- static int errcanChoices(char * name, int wasCancelled) {
- newtComponent form, retry, previous, menu, text, exitb, answer;
- char textBuf[1000];
-
- if (wasCancelled) {
- sprintf(textBuf, "You cancelled step \"%s\".\n\n", name);
- newtOpenWindow(15, 3, 50, 16, "Cancelled");
- } else {
- sprintf(textBuf, "An error occured during step \"%s\" of the "
- "install.\n\n", name);
- newtOpenWindow(15, 3, 50, 16, "Error");
- }
-
- form = newtForm(NULL, NULL, 0);
-
- strcat(textBuf, "You may retry that step, return to the previous step "
- "in the install, or see a menu of installation steps "
- "which will allow you to move around in the install "
- "more freely. It is not recommended to use the menu "
- "unless you are already familiar with Red Hat Linux. "
- "What would you like to do?");
-
- text = newtTextbox(1, 1, 48, 10, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text, textBuf);
-
- if (testing) {
- previous = newtButton(1, 12, "Previous");
- retry = newtButton(15, 12, "Retry");
- menu = newtButton(28, 12, "Menu");
- exitb = newtButton(39, 12, "Exit");
- newtFormAddComponents(form, text, previous, retry, menu, exitb, NULL);
- } else {
- previous = newtButton(5, 12, "Previous");
- retry = newtButton(20, 12, "Retry");
- menu = newtButton(38, 12, "Menu");
- newtFormAddComponents(form, text, previous, retry, menu, NULL);
- }
-
- answer = newtRunForm(form);
-
- newtPopWindow();
- newtFormDestroy(form);
-
- if (answer == previous)
- return DO_PREV;
- else if (answer == retry)
- return DO_RETRY;
- else if (answer == menu)
- return DO_MENU;
-
- newtFinished();
- exit(0);
- }
-
- static int stepMenu(struct installState * state, int currStep) {
- newtComponent form, listbox, okay, text;
- int firstStep = currStep;
- long i;
- int numChoices, listHeight;
- char buf[200];
-
- newtOpenWindow(15, 3, 50, 16, "Installation Steps");
-
- while (state->steps[firstStep].prev != -1)
- firstStep = state->steps[firstStep].prev;
-
- form = newtForm(NULL, NULL, 0);
-
- i = firstStep, numChoices = 0;
- do {
- numChoices++;
- i = state->steps[i].next;
- } while (state->steps[i].prev != -1 && state->steps[i].next != STEP_DONE);
- numChoices++;
-
- if (numChoices > 6)
- listHeight = 6;
- else
- listHeight = 0;
-
- listbox = newtListbox(10, 4, listHeight, NEWT_LISTBOX_RETURNEXIT);
-
- text = newtTextbox(1, 1, 48, 3, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text,
- "What step would you like to run? Steps with a * next "
- "to them have already been completed.");
-
- newtListboxAddEntry(listbox, " Continue with install",
- (void *) STEP_DONE + 1);
- for (i = firstStep; i < (firstStep + numChoices); i++) {
- if (state->steps[i].completed)
- strcpy(buf, "* ");
- else
- strcpy(buf, " ");
-
- strcat(buf, state->steps[i].name);
- newtListboxAddEntry(listbox, buf, (void *) i);
- }
-
- okay = newtButton(23, 11, "Ok");
- newtFormAddComponents(form, text, listbox, okay, NULL);
-
- newtRunForm(form);
-
- i = (long) newtListboxGetCurrent(listbox);
-
- newtFormDestroy(form);
- newtPopWindow();
-
- if (i == STEP_DONE + 1)
- return -1;
-
- return i;
- }
-
- static int getNextStep(struct installState * state, int lastStep, int lastrc) {
- int choice;
- int nextStep;
-
- if (state->lastChoice == DO_MENU)
- choice = DO_MENU;
- else if (lastrc == INST_ERROR) {
- choice = errcanChoices(state->steps[lastStep].name, 0);
- } else if (lastrc == INST_CANCEL) {
- choice = errcanChoices(state->steps[lastStep].name, 1);
- } else if (lastrc == INST_NOP) {
- choice = state->lastChoice;
- } else {
- choice = DO_NEXT;
- }
-
- switch (choice) {
- case DO_PREV:
- nextStep = state->steps[lastStep].prev;
- while (nextStep != -1 && state->steps[nextStep].skipOnCancel &&
- state->steps[nextStep].prev != -1)
- nextStep = state->steps[nextStep].prev;
-
- if (nextStep == -1 || nextStep == lastStep) {
- messageWindow("Cancelled", "I can't go to the previous step"
- " from here. You will have to try again.");
- nextStep = lastStep;
- }
- break;
-
- case DO_RETRY:
- nextStep = lastStep;
- break;
-
- case DO_MENU:
- nextStep = stepMenu(state, lastStep);
- if (nextStep == -1) {
- choice = DO_NEXT;
-
- if (lastrc)
- nextStep = lastStep;
- else
- nextStep = state->steps[lastStep].next;
- }
- break;
-
- case DO_NEXT: default:
- nextStep = state->steps[lastStep].next;
- break;
- }
-
- state->lastChoice = choice;
-
- return nextStep;
- }
-
- void doSuspend(void) {
- pid_t pid;
- int status;
-
- newtSuspend();
- if (!(pid = fork())) {
- printf("\n\nType <exit> to return to the install program.\n\n");
- execl("/bin/sh", "-/bin/sh", NULL);
- perror("error execing /bin/sh");
- sleep(5);
- exit(1);
- }
- waitpid(pid, &status, 0);
- newtResume();
- }
-
- static void setupSerialConsole(void) {
- int first = 1;
- struct stat sb;
- char * argv[10] = { "/usr/sbin/setconsole", "--speed", NULL, NULL, NULL };
- struct termios tos;
- speed_t speed;
-
- if (!first) return;
- first = 0;
-
- if (fstat(0, &sb)) {
- logMessage("error stat'ing stdin: %s", strerror(errno));
- return;
- }
-
- if (!S_ISCHR(sb.st_mode)) {
- logMessage("stdin isn't a character device!!! ack!");
- return;
- }
-
- if (major(sb.st_rdev) != 4) {
- if (minor(sb.st_rdev) == 64)
- argv[3] = "ttya";
- else
- argv[3] = "ttyb";
-
- tcgetattr(0, &tos);
- speed = cfgetospeed(&tos);
- switch (speed) {
- case B38400: argv[2] = "38400"; break;
- case B19200: argv[2] = "19200"; break;
- default: argv[2] = "9600"; break;
- }
-
- if (access("/mnt/usr/sbin/setconsole", X_OK)) {
- logMessage("/mnt/usr/sbin/setconsole does not exist -- skipping");
- return;
- }
-
- logMessage("setting up %s as serial console, speed is %s", argv[3],
- argv[2]);
- runProgramRoot(RUN_LOG, "/mnt", "/usr/sbin/setconsole", argv);
- }
- }
-
- static int configurePrinter(struct installState * state) {
- if (testing) {
- return doConfigurePrinters("/");
- } else if (!access("/mnt/usr/bin/lpr", X_OK)) {
- return doConfigurePrinters("/mnt");
- }
-
- return INST_NOP;
- }
-
- int main(int argc, char ** argv) {
- char ** argptr;
- int step = STEP_FIRST;
- int rc = 0;
- struct installState state;
- int i;
- int isForce = 0;
- int len = strlen(argv[0]);
- char * spaces;
- int isRescue = 0;
- DIR * dir;
- struct dirent * ent;
-
- spaces = strdup(" ");
-
- if (!strcmp(argv[0] + len - 6, "umount")) {
- return umountCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 5, "mount")) {
- return mountCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 5, "mkdir")) {
- return mkdirCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 5, "mknod")) {
- return mknodCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 3, "cat")) {
- return catCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 2, "rm")) {
- return rmCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 5, "chmod")) {
- return chmodCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 5, "lsmod")) {
- return lsmodCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 6, "mkswap")) {
- return mkswapCommand(argc, argv);
- } else if (!strcmp(argv[0] + len - 6, "swapon")) {
- return swaponCommand(argc, argv);
- }
-
- /* if this fails, it's okay -- it might help with free space though */
- unlink("/sbin/install");
-
- newtSetSuspendCallback(doSuspend);
-
- memset(&state, 0, sizeof(state));
- state.steps = installSteps; /* blind guess */
-
- argptr = argv + 1;
- while (*argptr) {
- if (!strcmp(*argptr, "--method")) {
- argptr++;
- if (!*argptr) {
- fprintf(stderr, "--method requires argument\n");
- exit(1);
- }
- state.method = findInstallMethod(*argptr);
- if (!state.method) {
- fprintf(stderr, "unknown install method: %s\n", *argptr);
- exit(1);
- }
- } else if (!strcmp(*argptr, "--force")) {
- isForce = 1;
- } else if (!strcmp(*argptr, "--rescue")) {
- isRescue = 1;
- } else if (!strcmp(*argptr, "--test")) {
- testing = 1;
- } else if (!strcmp(*argptr, "--pcmcia")) {
- argptr++;
- if (!*argptr) {
- fprintf(stderr, "--pcmcia requires argument\n");
- exit(1);
- }
- state.pcmcia = *argptr;
- } else if (!strcmp(*argptr, "--kernel")) {
- argptr++;
- if (!*argptr) {
- fprintf(stderr, "--kernel requires argument\n");
- exit(1);
- }
- state.kernel = *argptr;
- } else {
- /* skipping unknown arguments allows for future expansion */
- fprintf(stderr, "unknown argument: %s\n", *argptr);
- }
- argptr++;
- }
-
- if (!isRescue && !state.method) {
- fprintf(stderr, "--method argument is required\n");
- exit(1);
- }
-
- if (!testing && !isForce && (getpid() > 50)) {
- fprintf(stderr, "you're running me on a live system! that's ");
- fprintf(stderr, "incredibly stupid.\n");
- exit(1);
- }
-
- fprintf(stderr, "in second stage install\n");
-
- openLog();
-
- logMessage("second stage install running (version " VERSION " built "
- __DATE__ " " __TIME__ ")");
-
- spawnShell();
-
- newtInit();
- newtCls();
-
- newtDrawRootText(0, 0, "Red Hat Linux (C) 1997 Red Hat Software");
- newtPushHelpLine(NULL);
-
- if (isRescue) {
- do {
- rc = setupSCSIInterfaces(0, &state.dl);
- } while (rc);
-
- /* cut! we're out of here */
-
- newtFinished();
-
- execl("/bin/sh", "-/bin/sh", NULL);
- fprintf(stderr, "ack! I couldn't manage to execl() /bin/sh: %s",
- strerror(errno));
- while (1);
- }
-
- readNetConfig("/tmp", &state.netc);
-
- #ifndef __sparc__
- readKbdConfig("/tmp", &state.keyboard);
- #endif
-
- dir = opendir("/tmp");
- if (!dir)
- logMessage("failed to open directory /tmp: %s", strerror(errno));
- else {
- errno = 0;
- while ((ent = readdir(dir))) {
- if (!strncmp("ifcfg-", ent->d_name, 6)) break;
- }
-
- if (!ent && errno) {
- logMessage("error reading directory entry: %s", strerror(errno));
- } else if (ent) {
- logMessage("found network config file %s", ent->d_name);
- readNetInterfaceConfig("/tmp", ent->d_name + 6, &state.intf);
- }
- }
- closedir(dir);
-
- readModuleConf("/tmp", &state.dl);
-
- /* make sure we don't pick up any gunk from the outside world */
- putenv("PATH=/usr/bin:/bin:/sbin:/usr/sbin");
- putenv("LD_LIBRARY_PATH=");
-
- while (step != STEP_DONE) {
- i = strlen(state.steps[step].name);
- newtDrawRootText(0, 0 - i, state.steps[step].name);
- newtRefresh();
- rc = state.steps[step].fn(&state);
- if (!rc)
- state.steps[step].completed = 1;
-
- spaces[i] = '\0';
- newtDrawRootText(0, 0 - i, spaces);
- spaces[i] = ' ';
-
- step = getNextStep(&state, step, rc);
- }
-
- newtDrawRootText(0, 72, "Complete");
- winMessage(10, 3, 60, 16, "Done",
- "Congratulations, installation is complete.\n\n"
- "Remove the floppy from the drive and "
- "press return to reboot. For information on fixes which are "
- "available for this release of Red Hat Linux, consult the "
- "Errata available from http://www.redhat.com.\n\n"
- "Information on configuring your system is available in the post "
- "install chapter of the Official Red Hat Linux User's Guide.");
-
- umountFilesystems(&state.fstab);
-
- newtFinished();
-
- return 0;
- }
-